package errorx

import (
	"fmt"
	"strings"
)

// 参数错误
const defaultCode = 100001         // 默认参数
const paramsNotEmpty = 10005       //参数不为空
const paramsNotComplete = 100002   // 参数不全
const paramsTypeError = 100003     //参数类型错误
const paramsIdInvalid = 100004     //  参数无效
const paramsValidateError = 100005 //参数校验错误
// 用户错误
const userNotExist = 200001         // 用户不存在
const userNotLoggedIn = 200002      // 用户未登陆
const userAccountError = 200003     // 用户名或密码错误
const userAccountForbidden = 200004 // 用户账户已被禁用
const userHasExist = 200005         // 用户已存在
// 业务错误
const businessError = 300001 // 系统业务出现问题
// 系统错误
const systemInnerError = 400001 // 系统内部错误
// 数据错误
const dataNotFound = 500001       // 数据未找到
const dataIsWrong = 500002        // 数据有误
const dataAlreadyExisted = 500003 // 数据已存在
// 接口错误
const interfaceInnerInvokeError = 600001 // 系统内部接口调用异常
const interfaceOuterInvokeError = 600002 // 系统外部接口调用异常
const interfaceForbidden = 600003        // 接口禁止访问
const interfaceAddressInvalid = 600004   // 接口地址无效
const interfaceRequestTimeout = 600005   // 接口请求超时
const interfaceExceedLoad = 600006       // 接口负载过高
// 权限错误
const permissionNoAccess = 700001 // 没有访问权限
const tokenExpire = 700002

type CodeError struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
}

type CodeErrorResponse struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
}

func NewCodeError(code int, msg string) error {
	return &CodeError{Code: code, Message: msg}
}

func NewDefaultError(msg string) error {
	return NewCodeError(defaultCode, msg)
}

func NewParamsNotComplete(msg string) error {
	return NewCodeError(paramsNotComplete, msg)
}

func NewParamsNotEmpty(msg string) error {
	return NewCodeError(paramsNotEmpty, msg)
}

func NewParamsTypeError(msg string) error {
	return NewCodeError(paramsTypeError, msg)
}

func NewpPramsIdInvalid(msg string) error {
	return NewCodeError(paramsIdInvalid, msg)
}

func NewpParamsValidateError(msg string) error {
	if strings.HasPrefix(msg, "field") && strings.HasSuffix(msg, "is not set") {
		msg = strings.TrimPrefix(msg, "field")
		msg = strings.TrimSuffix(msg, "is not set")
		msg = strings.TrimSpace(msg)
		msg = fmt.Sprintf("参数[%s]未设置", msg)
	}
	return NewCodeError(paramsValidateError, msg)
}

func NewUserNotExist(msg string) error {
	return NewCodeError(userNotExist, msg)
}

func NewUserNotLoggedIn(msg string) error {
	return NewCodeError(userNotLoggedIn, msg)
}

func NewUserAccountError(msg string) error {
	return NewCodeError(userAccountError, msg)
}

func NewUserAccountForbidden(msg string) error {
	return NewCodeError(userAccountForbidden, msg)
}

func NewUserHasExist(msg string) error {
	return NewCodeError(userHasExist, msg)
}

func NewBusinessError(msg string) error {
	if strings.HasPrefix(msg, "field") && strings.HasSuffix(msg, "is not set") {
		msg = strings.TrimPrefix(msg, "field")
		msg = strings.TrimSuffix(msg, "is not set")
		msg = strings.TrimSpace(msg)
		msg = fmt.Sprintf("参数[%s]未设置", msg)
	}
	return NewCodeError(businessError, msg)
}

func NewSystemInnerError(msg string) error {
	return NewCodeError(systemInnerError, msg)
}

func NewDataNotFound(msg string) error {
	return NewCodeError(dataNotFound, msg)
}

func NewDataIsWrong(msg string) error {
	return NewCodeError(dataIsWrong, msg)
}

func NewDataAlreadyExisted(msg string) error {
	return NewCodeError(dataAlreadyExisted, msg)
}

func NewInterfaceInnerInvokeError(msg string) error {
	return NewCodeError(interfaceInnerInvokeError, msg)
}

func NewInterfaceOuterInvokeError(msg string) error {
	return NewCodeError(interfaceOuterInvokeError, msg)
}

func NewInterfaceForbidden(msg string) error {
	return NewCodeError(interfaceForbidden, msg)
}

func NewInterfaceAddressInvalid(msg string) error {
	return NewCodeError(interfaceAddressInvalid, msg)
}

func NewInterfaceRequestTimeout(msg string) error {
	return NewCodeError(interfaceRequestTimeout, msg)
}

func NewInterfaceExceedLoad(msg string) error {
	return NewCodeError(interfaceExceedLoad, msg)
}

func NewPermissionNoAccess(msg string) error {
	return NewCodeError(permissionNoAccess, msg)
}

func NewTokenExpire(msg string) error {
	return NewCodeError(tokenExpire, msg)
}

func (e *CodeError) Error() string {
	return e.Message
}

func (e *CodeError) Data() *CodeErrorResponse {
	return &CodeErrorResponse{
		Code:    e.Code,
		Message: e.Message,
	}
}
